
#include "Flag.h"
#include "Ship.h"
#include "Player.h"
#include "Graphics/TextureManager.h"
#include "Settings.h"
#include "GameState.h"

#include <GL/gl.h>
#include <iostream>

Flag::Flag(unsigned team_id, Vector2D home_position) :
    team_id(team_id), home_position(home_position) {

    position = home_position;
    holding_ship = NULL;

    size = Settings::instance().getFloatValue("flags", "size");
    held_size = Settings::instance().getFloatValue("flags", "held_size");

    std::string path;
    if(team_id == 0){
        path = Settings::instance().getStringValue("flags", "red_flag_path");
    }
    else if(team_id == 1){
        path = Settings::instance().getStringValue("flags", "blue_flag_path");
    }
    texture_id = TextureManager::instance().loadTexture(path);
}

Flag::~Flag(){

}

void Flag::render(void){
    // TODO render differently depending on whether the flag is currently
    // held by someone.
   
    glPushMatrix();
    glColor3f(1.0f, 1.0f, 1.0f); // TODO color dependant on team color

    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    
    glEnable(GL_ALPHA_TEST);
    glAlphaFunc(GL_GREATER, 0.0f);

    glEnable(GL_TEXTURE_2D);
    TextureManager::instance().bindTexture(texture_id);

    if(holding_ship){
        Vector2D pos = holding_ship->getPosition();
        Vector2D v = -0.27f * holding_ship->getHeading();
        v.rotate(45.0f);
        pos.add(v);

        position = pos;

        glTranslatef(position.x, position.y, 0.0f);
        glBegin(GL_QUADS);
          glTexCoord2f(0.0f, 1.0f); glVertex3f(-held_size, -held_size, 0.0f);
          glTexCoord2f(0.0f, 0.0f); glVertex3f(-held_size,  held_size, 0.0f);
          glTexCoord2f(1.0f, 0.0f); glVertex3f( held_size,  held_size, 0.0f);
          glTexCoord2f(1.0f, 1.0f); glVertex3f( held_size, -held_size, 0.0f);
        glEnd();
    }
    else{
        glTranslatef(position.x, position.y, 0.0f);
        glBegin(GL_QUADS);
          glTexCoord2f(0.0f, 1.0f); glVertex3f(-size, -size, 0.0f);
          glTexCoord2f(0.0f, 0.0f); glVertex3f(-size,  size, 0.0f);
          glTexCoord2f(1.0f, 0.0f); glVertex3f( size,  size, 0.0f);
          glTexCoord2f(1.0f, 1.0f); glVertex3f( size, -size, 0.0f);
        glEnd();
    }

    glDisable(GL_ALPHA_TEST);
    glDisable(GL_TEXTURE_2D);
    glDisable(GL_BLEND);
    glPopMatrix();
}

void Flag::renderMinimap(void){
    glPushMatrix();

    if(team_id == 0){
        glColor3f(1.0f, 0.0f, 0.0f); // TODO color dependant on team color
    }
    else{
        glColor3f(0.0f, 0.0f, 1.0f);
    }

    glTranslatef(position.x, position.y, 0.0f);
    glPointSize(3.0f);
    glBegin(GL_POINTS);
      glVertex3f(0.0f, 0.0f, 0.0f);
    glEnd();


    glPopMatrix();
}

void Flag::update(void){

}

bool Flag::active(void){
    return true; // flags are always active
}

bool Flag::resolveCollision(Ship *ship){
    if(ship == NULL || holding_ship != NULL || !ship->active()){
        return false; // makes no sense to check for collisions if flag is being held by someone.
    }

    if((ship->getPosition()-position).length() < (size+ship->getSize())){
        if(team_id == ship->getControllingPlayer()->getTeamId()){
            position = home_position;

            if(ship->resetHeldFlags()){
                GameState::instance().changeTeamScore(ship->getControllingPlayer()->getTeamId(), 1);
                // TODO: Score a point here for the appropriate team
            }
        }
        else{
            holding_ship = ship;
            ship->grabFlag(this);
            return true;
        }
    }

    return false;
}


bool Flag::resolveCollision(Weapon *weapon){
    return false; // flags cant be destroyed
}


bool Flag::resolveCollision(Map *map){
    return false; // flags cant collide with the map.
}


void Flag::reset(void){
    position = home_position;
    holding_ship = NULL;
}


void Flag::drop(void){
    std::cout << "dropping flag" << std::endl;
    holding_ship = NULL;    
}


Vector2D Flag::getPosition(void){
    return position;
}


Vector2D Flag::getHomePosition(void){
    return home_position;
}

Ship* Flag::getHoldingShip(void){
    return holding_ship;
}

